﻿using MyMathLab;
namespace MyMath
{
    internal class Program
    {
        /// <summary>
        /// 利用近三十年的数据拟合曲线并预测2021年中国的GDP
        /// </summary>
        /// <param name="year">要预测的年份</param>
        /// <returns></returns>
        static double fitting(int year)
        {
            //观察数据可知1991-2021年中国GDP的图表符合指数型增长模型
            //创建类将年份和GDP总额联系起来
            //计算参数a，b
            //拟合并算出2021年的GDP并计算R1来评估拟合效果
            Points[] obj = new Points[30];
            obj[0] = new Points(1991, 383373318083);
            obj[1] = new Points(1992, 426915712715);
            obj[2] = new Points(1993, 4447312824335);
            obj[3] = new Points(1994, 564324670008);
            obj[4] = new Points(1995, 734547898224);
            obj[5] = new Points(1996, 863746717507);
            obj[6] = new Points(1997, 961603952954);
            obj[7] = new Points(1998, 1029043097558);
            obj[8] = new Points(1999, 1093997267277);
            obj[9] = new Points(2000, 1211346869600);
            obj[10] = new Points(2001, 1339395718862);
            obj[11] = new Points(2002, 1470550015077);
            obj[12] = new Points(2003, 1660287965663);
            obj[13] = new Points(2004, 1955347004965);
            obj[14] = new Points(2005, 2285965892364);
            obj[15] = new Points(2006, 2752131773358);
            obj[16] = new Points(2007, 3550342737009);
            obj[17] = new Points(2008, 4594307032667);
            obj[18] = new Points(2009, 5101703073088);
            obj[19] = new Points(2010, 6087163874510);
            obj[20] = new Points(2011, 7551500124197);
            obj[21] = new Points(2012, 8532229986993);
            obj[22] = new Points(2013, 9570406235659);
            obj[23] = new Points(2014, 10475682920597);
            obj[24] = new Points(2015, 11061553079871);
            obj[25] = new Points(2016, 11233276536744);
            obj[26] = new Points(2017, 12310409370894);
            obj[27] = new Points(2018, 13894817549380);
            obj[28] = new Points(2019, 14279937500608);
            obj[29] = new Points(2020, 14687673892882);
            for (int i = 0; i < 30; i++)
            {
                //初步处理数据：对Y取对数
                obj[i].Y = Math.Log(obj[i].Y, Math.E);
            }
            //计算线性回归系数
            double a, b, m = 0, n = 0;
            double avgx = 0, avgz = 0, totalx = 0, totalz = 0;
            for (int i = 0; i < 30; i++)
            {
                totalx += obj[i].X;
                totalz += obj[i].Y;
            }
            avgx = totalx / 30;
            avgz = totalz / 30;
            for (int j = 0; j < 30; j++)
            {
                m += (obj[j].X - avgx) * (obj[j].Y - avgz);
                n += (obj[j].X - avgx) * (obj[j].X - avgx);
            }
            a = m / n;
            b = avgz - a * avgx;
            double z = a * year + b;
            //还原对数
            return Math.Pow(Math.E, z);
        }
        /// <summary>
        /// 主函数
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("请输入要预测的年份：");
            int year = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine($"预测{year}年中国GDP的数据为 " + Program.fitting(year));
        }
    }
}